package com.kum.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kum.domain.constant.Sign;
import com.kum.domain.dto.SignDto;
import com.kum.domain.entity.SysFaceData;
import com.kum.domain.entity.SysSign;
import com.kum.domain.entity.SysUser;
import com.kum.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @version V1.0
 * @Package com.kum.service
 * @auhter 枯木Kum
 * @date 2021/3/10-10:55 AM
 */

@Service
@Slf4j
public class SignService {
    @Autowired
    private FaceService faceService;
    @Autowired
    private SysFaceDataService sysFaceDataService;
    @Autowired
    private SysSignService sysSignService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private RedisUtils redisUtils;

    /**
     * 发起签到
     * <p>将签到信息插入到数据库之中,再缓存到Redis之中存储到今天结束</p>
     *
     * @param signDto
     * @return 是否成功签到
     */
    public boolean startSign(SignDto signDto) {
        boolean isSuccess = contrastFaceData(signDto);
        if (isSuccess) {
            // key由默认前缀 + 用户ID + 签到时间类型组成
            String signType = Sign.getCurrentSginTimeType();
            String signKey = Sign.kEY + signDto.getUserId() + signType;
            SysUser sysUser = sysUserService.findById(signDto.getUserId());
            SysSign sysSign = new SysSign().toBuilder().sysUser(sysUser).signType(signType).signDate(new Date()).build();
            sysSignService.save(sysSign);
            redisUtils.putOneDay(signKey, sysSign);
            redisUtils.expireKeyAt(signKey, getTodayEndDate());
        }
        return isSuccess;

    }

    /**
     * 将用户传递的照片数据与数据库之中的进行对比
     *
     * @param signDto
     */
    public boolean contrastFaceData(SignDto signDto) {
        SysFaceData userFaceData = sysFaceDataService.findByUserId(signDto.getUserId());
        return faceService.contrast(userFaceData.getFaceData(), signDto.getCurrentFaceDate());

    }

    /**
     * 从缓存获取今日签到的用户列表
     *
     * @return
     */
    public List<SysSign> getCacheSignList() {
        String prefix = redisUtils.getPrefix(Sign.kEY);
        List<SysSign> sysSigns = JSON.parseArray(prefix, SysSign.class);
        return sysSigns;
    }


    /**
     * 获取今日结束之时的时间
     *
     * @return
     */
    private Date getTodayEndDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 统计用户签到信息
     *
     * @param cacheSignList
     * @return 返回各个项目签到信息以及总签到数
     */
    public JSONArray statistic(List<SysSign> cacheSignList) {
        Map<String, Integer> map = new HashMap<>();
        for (SysSign sysSign : cacheSignList) {
            SysUser sysUser = sysSign.getSysUser();
            map.merge(sysUser.getTargetProject(), 1, (a, b) -> a + b);
        }
        JSONArray jsonArray = new JSONArray();
        map.keySet().forEach(key -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("targetProject",key);
            jsonObject.put("num",map.get(key));
            jsonArray.set(jsonArray.size(),jsonObject);
        });

        return jsonArray;

    }

    /**
     * 获取本周(月)的排行榜数据
     * @param type week: 本周，month:本月
     * @return
     */
    public List<SysSign> getAttendanceList(String type){
        HashMap<String, String> map = new HashMap<>();
        if(type.equals(Sign.CURRENT_WEEK_SIGN)){
            map = Sign.getWeekStartAndEndTime();
        }else if(type.equals(Sign.CURRENT_MONTH_SIGN)){
            map = Sign.getMonthStartAndEndTime();
        }
        return sysSignService.findByStartAndEndDate(map.get("start"),map.get("end"));
    }

    /**
     * 根据自定日期间隔获取排行榜数据
     * @param start 开始时间
     * @param end 结束时间
     * @return
     */
    public List<SysSign> getAttendanceList(Date start, Date end){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sysSignService.findByStartAndEndDate(sdf.format(start),sdf.format(end));
    }

    /**
     * 获取今日未签到用户
     * @return
     */
    public List<String> getNoSignUserList(){
        List<SysSign> signUsers = getCacheSignList();
        List<String> userNames = new ArrayList<>();
        sysUserService.list().forEach(sysUser -> userNames.add(sysUser.getName()));
        signUsers.forEach(sysSign -> {
            String userName = sysSign.getSysUser().getName();
            if(userNames.contains(userName)){
                userNames.remove(userName);
            }
        });

        return userNames;

    }

}
